#include "HDC1080.h"



void __HDC1080_SDA_Set()
{
	HAL_GPIO_WritePin(HDC1080_SDA_GPIO_PORT, HDC1080_SDA_GPIO_PIN, GPIO_PIN_SET);
}

void __HDC1080_SDA_Reset()
{
	HAL_GPIO_WritePin(HDC1080_SDA_GPIO_PORT, HDC1080_SDA_GPIO_PIN, GPIO_PIN_RESET);
}

void __HDC1080_SCL_Set()
{
	HAL_GPIO_WritePin(HDC1080_SCL_GPIO_PORT, HDC1080_SCL_GPIO_PIN, GPIO_PIN_SET);
}

void __HDC1080_SCL_Reset()
{
	HAL_GPIO_WritePin(HDC1080_SCL_GPIO_PORT, HDC1080_SCL_GPIO_PIN, GPIO_PIN_RESET);
}



void __HDC1080_i2c_delay(void)
{
	uint16_t i=HDC1080_I2C_DELAY;
	while(i--);
}

void __HDC1080_i2c_start(void)
{
/*    _____
 *SDA      \_____________
 *    __________
 *SCL           \________
 */
	__HDC1080_SDA_Set();
	__HDC1080_SCL_Set();
	__HDC1080_i2c_delay();
	__HDC1080_SDA_Reset();
	__HDC1080_i2c_delay();
	__HDC1080_SCL_Reset();
	__HDC1080_i2c_delay();
}

void __HDC1080_i2c_stop(void)
{
/*               _______
 *SDA __________/
 *          ____________
 *SCL _____/
 */
	__HDC1080_SDA_Reset();
	__HDC1080_SCL_Set();
	__HDC1080_i2c_delay();
	__HDC1080_SDA_Set();
}

uint8_t __HDC1080_i2c_waitACK(void)
{
	uint32_t timeout=0;
	__HDC1080_SDA_Set();
	__HDC1080_i2c_delay();
	__HDC1080_SCL_Set();
	__HDC1080_i2c_delay();
	while(HAL_GPIO_ReadPin(HDC1080_SDA_GPIO_PORT, HDC1080_SDA_GPIO_PIN))
	{
		timeout++;
		if(timeout>HDC1080_I2C_TIMEOUT) return 1;
	}
	__HDC1080_SCL_Reset();
	__HDC1080_i2c_delay();
	return 0;
}

void __HDC1080_i2c_sendACK(void)
{
    /*
     *    ____         _____
     *SDA     \_______/
     *           ____
     *SCL ______/    \______

     */
	__HDC1080_SDA_Reset();
	__HDC1080_i2c_delay();
	__HDC1080_SCL_Set();
	__HDC1080_i2c_delay();
	__HDC1080_SCL_Reset();
	__HDC1080_i2c_delay();
	__HDC1080_SDA_Set();
}

void __HDC1080_i2c_sendNACK(void)
{
/*
 *    __________________
 *SDA
 *           ____
 *SCL ______/    \______

 */
	__HDC1080_SDA_Set();
	__HDC1080_i2c_delay();
	__HDC1080_SCL_Set();
	__HDC1080_i2c_delay();
	__HDC1080_SCL_Reset();
	__HDC1080_i2c_delay();
}


void __HDC1080_i2c_SendByte(uint8_t data)
{
	for(int i=0;i<8;i++)
	{
		if(data&0x80)
		{
			__HDC1080_SDA_Set();
		}else {
			__HDC1080_SDA_Reset();
		}
		__HDC1080_i2c_delay();
		__HDC1080_SCL_Set();
		__HDC1080_i2c_delay();
		__HDC1080_SCL_Reset();
		if(i==7)
		{
			__HDC1080_SDA_Set();
		}
		data<<=1;
		__HDC1080_i2c_delay();
	}
}

uint8_t __HDC1080_i2c_ReadByte(void)
{
	uint8_t data;
	for(int i=0;i<8;i++)
	{
		data<<=1;
		__HDC1080_SCL_Set();
		__HDC1080_i2c_delay();
		if(HAL_GPIO_ReadPin(HDC1080_SDA_GPIO_PORT, HDC1080_SDA_GPIO_PIN)) data++;
		__HDC1080_SCL_Reset();
		__HDC1080_i2c_delay();
	}
	return data;
}



uint8_t HDC1080_WriteData(uint16_t MemAddress,uint8_t *data,int size)
{
	int count=size;
	uint8_t *pdata=data;


	__HDC1080_i2c_start();

	__HDC1080_i2c_SendByte(HDC1080_ADDR);
	if(__HDC1080_i2c_waitACK()==1) return 1;//no ACK
	__HDC1080_i2c_SendByte(MemAddress);
	if(__HDC1080_i2c_waitACK()==1) return 1;//no ACK


	while(count)
	{
		__HDC1080_i2c_SendByte(*pdata);
		pdata++;
		if(__HDC1080_i2c_waitACK()==1) return 1;//no ACK
		count--;
	}
	__HDC1080_i2c_stop();
	HAL_Delay(10);
	return 0;

}


uint8_t HDC1080_ReadData(uint16_t MemAddress,uint8_t *buff,int size)
{
	int count=size,res=HAL_OK;
	uint8_t *pdata=buff;

	__HDC1080_i2c_start();

	__HDC1080_i2c_SendByte(HDC1080_ADDR);
	if(__HDC1080_i2c_waitACK()==1) return 1;//no ACK
	__HDC1080_i2c_SendByte(MemAddress);
	if(__HDC1080_i2c_waitACK()==1) return 1;//no ACK

	HAL_Delay(20);


	__HDC1080_i2c_start();
	__HDC1080_i2c_SendByte(HDC1080_ADDR+1);
	if(__HDC1080_i2c_waitACK()==1) return 1;//no ACK
	while(count)
	{
		*pdata++=__HDC1080_i2c_ReadByte();
		if(count>1)
		{
			__HDC1080_i2c_sendACK();
		}else {
			__HDC1080_i2c_sendNACK();
		}
		count--;
	}
	__HDC1080_i2c_stop();
	return res;

}



HDC_TEMP_HUM HDC;




/*
 * @brief 温湿度传感器初始化
 * @retval 初始化结果
 */
uint8_t HDC1080_Init(void)
{
    uint16_t data;
    uint8_t buf[2];
    uint16_t config = HDC1080_CONFIG_RST | HDC1080_CONFIG_MODE | HDC1080_CONFIG_TRES_14 | HDC1080_CONFIG_HRES_14;
    buf[0]=config>>8;
    buf[1]=config&0xff;


    //软复位
    HDC1080_WriteData(HDC1080_CONFIG, buf,2);
    HAL_Delay(100);
    //读ID
    HDC1080_ReadData(HDC1080_MANUFID, buf, 2);
    data = (buf[0]<<8)+buf[1];
    printf("HDC1080-ID->0x%x\r\n",data);
    if(data!=0x5449) return 1;
    //读ID
    HDC1080_ReadData(HDC1080_DEVICEID, buf, 2);
    data = (buf[0]<<8)+buf[1];
    if(data!=0x1050) return 1;
    return 0;
}




/*
 * @brief 获取温度(浮点型,单位摄氏度)
 * @retval 转换结果
 */
float HDC1080_Get_Temperature(void)
{
    float data;
    uint8_t buf[2];
    HDC1080_ReadData(HDC1080_TEMPERATURE, buf, 2);
//    SCB_CleanInvalidateDCache();
    data=((buf[0]<<8)+buf[1]);
    data /= 65536.0;
    data *= 165.0;
    data -= 40.0;
    HDC.board_temperature=data;
    return data;
}


/*
 * @brief 获取湿度(浮点型,百分比)
 * @retval 转换结果
 */
float HDC1080_Get_Humidity(void)
{
    float data;
    uint8_t buf[2];
    HDC1080_ReadData(HDC1080_HUMIDITY, buf, 2);
//    SCB_CleanInvalidateDCache();
    data=(buf[0]<<8)+buf[1];
    data /= 65536.0;
    HDC.board_humidity=data;
    return data;
}



void HDC1080_Data_Update()
{
	HDC1080_Get_Temperature();
	HDC1080_Get_Humidity();
}

